back to index.

FNA OBJ loader

Starting my new job with Flightaware next week, have spent the past few days trying to wrap up a few things I was working on for the last while. Further to my terrain rendering stuff with the tower defence game, I have been playing about a bit with more 3d. Seeing Kleadron's work on an obj loader in the FNA Discord, I got stoked to put something together myself. Everything was very straigthforward, and took about two hours. It doesn't yet support all parts of obj files, I assume a single mesh, and don't think about materials at all.

FNA Obj loader with image of loaded mage model.

OBJ loader

Below is the meat of the obj loader. This code is setup to spit out lists of vertices that you then bind into a vertexbuffer at draw time. The loader takes care of all the actual generation of faces from the input.

if (line.Length > 0) { string[] split = line.Split(' '); if (split[0] == "v") { //Vertex lines. VertexPositionColor newVertex = new VertexPositionColor(); newVertex.Position = new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3])); newVertex.Color = new Color(newVertex.Position.X, newVertex.Position.Y, newVertex.Position.Z); _vertices.Add(newVertex); vertsCount++; } else if (split[0] == "vn") { //Vertex normal lines. Vector3 newNormal = new Vector3(float.Parse(split[1]), float.Parse(split[2]), float.Parse(split[3])); _normals.Add(newNormal); } else if (split[0] == "f") { //If the obj file has normals associated, include them in the indiceNormals list. if (split[1].Contains("//")) { _indices.Add(int.Parse(split[1].Split("//")[0])); _indiceNormals.Add(int.Parse(split[1].Split("//")[1])); _indices.Add(int.Parse(split[2].Split("//")[0])); _indiceNormals.Add(int.Parse(split[2].Split("//")[1])); _indices.Add(int.Parse(split[3].Split("//")[0])); _indiceNormals.Add(int.Parse(split[3].Split("//")[1])); } //Else we just include the indices. else { _indices.Add(int.Parse(split[1])); _indices.Add(int.Parse(split[2])); _indices.Add(int.Parse(split[3])); } facesCount++; } } SNIP for (int i = 0; i < _indices.Count; i++) { modelVertices.Add(_vertices[_indices[i]-1]); } SNIP public List getModel() { return modelVertices; } public List getModelWithNormals() { List returnVertices = new List(); for (int i = 0; i < _indices.Count; i++) { VertexPositionNormalTexture newVert = new VertexPositionNormalTexture(); newVert.Position = _vertices[_indices[i] - 1].Position; newVert.Normal = _normals[_indiceNormals[i] - 1]; newVert.TextureCoordinate = new Vector2(0, 1); returnVertices.Add(newVert); } return returnVertices; }


Comment